package com.java.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.java.auth.mapper.SysMenuMapper;
import com.java.auth.mapper.SysRoleMenuMapper;
import com.java.auth.service.SysMenuService;
import com.java.auth.utils.MenuHelper;
import com.java.common.utils.R;
import com.java.model.system.SysMenu;
import com.java.model.system.SysRoleMenu;
import com.java.vo.system.AssginMenuVo;
import com.java.vo.system.MetaVo;
import com.java.vo.system.RouterVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Autowired
    private SysMenuMapper sysMenuMapper;
    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;

    /**
     * 菜单列表接口
     * @return
     */
    @Override
    public R findNodes() {

        //1获取所有菜单选项
        List<SysMenu> sysMenuList = sysMenuMapper.selectList(null);
        //2封装成树形结构
        List<SysMenu> res = MenuHelper.buildTree(sysMenuList);

        return R.ok(res);
    }

    /**
     * 删除菜单
     * @param id
     * @return
     */
    @Override
    public R removeById(Long id) {
        int count = sysMenuMapper.selectCount(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getParentId, id));
        if (count > 0) {
            return R.fail().message("菜单不可删除！").code(201);
        }
        sysMenuMapper.deleteById(id);
        return R.ok().message("删除成功！");
    }

    /**
     * 根据角色获取授权权限数据
     *
     * @param roleId
     * @return
     */
    @Override
    public R findMenuByRole(Long roleId) {
        //1获取所有状态为1的菜单选项，
        List<SysMenu> sysMenuList = sysMenuMapper.selectList(new QueryWrapper<SysMenu>().eq("status",1));
        //2.根据角色id获取所拥有的菜单权限
        LambdaQueryWrapper<SysRoleMenu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysRoleMenu::getRoleId,roleId);
        List<SysRoleMenu> sysRoleMenusList = sysRoleMenuMapper.selectList(lambdaQueryWrapper);

        //3.取出菜单id，并将菜单中已选择项置为true
        List<Long> roleMenuList = sysRoleMenusList.stream().map(c -> c.getMenuId()).collect(Collectors.toList());

        for(SysMenu sysMenu:sysMenuList){
            if(roleMenuList.contains(sysMenu.getId())){
                sysMenu.setSelect(true);
            }
        }
        //4.封装返回结果
        List<SysMenu> sysMenus = MenuHelper.buildTree(sysMenuList);

        return R.ok(sysMenus);
    }

    /**
     * 保存角色权限
     *
     * @param assignMenuVo
     * @return
     */
    @Override
    public R assignPermToRole(AssginMenuVo assignMenuVo) {
        //1.删除角色原有权限
        LambdaQueryWrapper<SysRoleMenu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysRoleMenu::getRoleId,assignMenuVo.getRoleId());
        int rows = sysRoleMenuMapper.delete(lambdaQueryWrapper);
        log.info("SysMenuServiceImpl.assignPermToRole 业务已经完成,结果:{}", rows);
        //2.添加角色现有权限
        List<Long> menuIdList = assignMenuVo.getMenuIdList();
        for(Long menuId:menuIdList){
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setMenuId(menuId);
            sysRoleMenu.setRoleId(assignMenuVo.getRoleId());
            sysRoleMenuMapper.insert(sysRoleMenu);
        }
        return R.ok().message("修改成功！");
    }

    /**
     * 根据用户id获取菜单权限
     *
     * @param userId
     * @return
     */
    @Override
    public List<RouterVo> findUserMenuByUserId(Long userId) {
        List<SysMenu> sysMenuList = null;
        //判断是否为超级管理员
        if(userId.intValue() == 1){
            //获取菜单列表
            sysMenuList = this.list(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getStatus, 1).orderByAsc(SysMenu::getSortValue));
        }else{
            sysMenuList = sysMenuMapper.findMenusListByUserId(userId);
        }
        //封装返回数据，构建成树形结构
        List<SysMenu> sysMenuListTree = MenuHelper.buildTree(sysMenuList);
        log.info("SysMenuServiceImpl.findUserMenuByUserId 业务已经完成,结果:{}", sysMenuListTree);
        List<RouterVo> routerVoList = this.buildMenus(sysMenuListTree);
        log.info("SysMenuServiceImpl.findUserMenuByUserId 业务已经完成,结果:{}", routerVoList);

        return routerVoList;
    }

    private List<RouterVo> buildMenus(List<SysMenu> menus) {
        List<RouterVo> routers = new LinkedList<RouterVo>();
        for (SysMenu menu : menus) {
            RouterVo router = new RouterVo();
            router.setHidden(false);
            router.setAlwaysShow(false);
            router.setPath(getRouterPath(menu));
            router.setComponent(menu.getComponent());
            router.setMeta(new MetaVo(menu.getName(), menu.getIcon()));
            List<SysMenu> children = menu.getChildren();
            //如果当前是菜单，需将按钮对应的路由加载出来，如：“角色授权”按钮对应的路由在“系统管理”下面
            if(menu.getType().intValue() == 1) {
                List<SysMenu> hiddenMenuList = children.stream().filter(item -> !StringUtils.isEmpty(item.getComponent())).collect(Collectors.toList());
                for (SysMenu hiddenMenu : hiddenMenuList) {
                    RouterVo hiddenRouter = new RouterVo();
                    hiddenRouter.setHidden(true);
                    hiddenRouter.setAlwaysShow(false);
                    hiddenRouter.setPath(getRouterPath(hiddenMenu));
                    hiddenRouter.setComponent(hiddenMenu.getComponent());
                    hiddenRouter.setMeta(new MetaVo(hiddenMenu.getName(), hiddenMenu.getIcon()));
                    routers.add(hiddenRouter);
                }
            } else {
                if (!CollectionUtils.isEmpty(children)) {
                    if(children.size() > 0) {
                        router.setAlwaysShow(true);
                    }
                    router.setChildren(buildMenus(children));
                }
            }
            routers.add(router);
        }
        log.info("SysMenuServiceImpl.buildMenus 业务已经完成,结果:{}", routers);
        return routers;

    }
    /**
     * 获取路由地址
     *
     * @param menu 菜单信息
     * @return 路由地址
     */
    public String getRouterPath(SysMenu menu) {
        String routerPath = "/" + menu.getPath();
        if(menu.getParentId().intValue() != 0) {
            routerPath = menu.getPath();
        }
        return routerPath;
    }
    /**
     * 根据用户id获取操作权限
     *
     * @param userId
     * @return
     */
    @Override
    public List findPermsByUserId(Long userId) {
        //超级管理员admin账号id为：1
        List<SysMenu> sysMenuList = null;
        if (userId.longValue() == 1) {
            sysMenuList = this.list(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getStatus, 1));
        } else {
            sysMenuList = sysMenuMapper.findMenusListByUserId(userId);
        }
        List<String> permsList = sysMenuList.stream().filter(item -> item.getType() == 2).map(item -> item.getPerms()).collect(Collectors.toList());
        return permsList;
    }

}
